home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / comm / bbs / cit_src_AD08.lha / va.c < prev    next >
C/C++ Source or Header  |  1997-07-27  |  24KB  |  913 lines

  1. /*
  2.  *                              va.c
  3.  *
  4.  * Virtual Room Administrator for the C-86 bulletin board system.
  5.  */
  6.  
  7. /*
  8.  *                              history
  9.  *
  10.  * 88Apr19 HAW  1.2: Fix for checking PEONS against local msgs.
  11.  * 88Apr08 HAW  1.1: Fix for not turning off a room's inuse flag.
  12.  * 88Jan19 HAW  Created.
  13.  */
  14.  
  15. #define V_ADMIN 1
  16.  
  17. #include "ctdl.h"
  18. #include "math.h"
  19. void VReName(void);
  20. int  mPrintf(char *format, ...) {return 0; }  /* stub to quiet the linker */
  21.  
  22. /*
  23.  *                              contents
  24.  *
  25.  */
  26.  
  27. FILE            *VaLog = NULL;
  28. char            RunMode;
  29. VirtualRoom     *VRoomTab = NULL;
  30. int             VirtSize;
  31. VirtNet         *VirtNetList = NULL;
  32.  
  33. extern MessageBuffer   msgBuf;          /* The -sole- message buffer    */
  34. extern CONFIG    cfg;                   /* Configuration variables      */
  35. extern aRoom     roomBuf;               /* Room buffer                  */
  36. extern rTable    *roomTab;
  37. extern NetTable  *netTab;
  38. extern NetBuffer netBuf;
  39. extern FILE      *netfl, *roomfl;
  40.  
  41. extern FILE *msgfl, *msgfl2;
  42.  
  43. extern int       thisRoom;              /* Current room */
  44. extern int       thisNet;               /* Current node in use */
  45.  
  46. /*
  47.  * main()
  48.  *
  49.  * This is the main manager.
  50.  */
  51. int main(int , char **);
  52. int main(argc, argv)
  53. char **argv;
  54. int  argc;
  55. {
  56.     cfg.weAre = UTILITY;
  57.     if (!readSysTab(TRUE, TRUE)) {
  58.         exit(1);
  59.     }
  60.  
  61.     if (access(LOCKFILE, 0) != ERROR) {
  62.         printf("Please do not run VirtAdmn using Outside Commands.\n");
  63.         writeSysTab();
  64.         exit(1);
  65.     }
  66.  
  67.     GenInit();
  68.     InitVirtual();      /* kludge ... ? */
  69.     AnalyzeArguments(argc, argv);
  70.     splitIt("Citadel Virtual Room Administrator %s\n%s\n", VERSION_NAME,
  71.         COPYRIGHT);
  72.     splitIt("\nNode is %s\n", cfg.nodeName + cfg.codeBuf);
  73.     switch (RunMode) {
  74.         case BATCH:
  75.                 splitIt("Batch mode.\n");
  76.                 BatchMode();
  77.                 break;
  78.         case NORMAL:
  79.                 splitIt("\n\n\n");
  80.                 InteractMode();
  81.                 break;
  82.         default: splitIt("very bad value for run mode!");
  83.     }
  84.     writeSysTab();
  85.     UpdVirtStuff();             /* kludge ... ? */
  86. return 0;
  87. }
  88.  
  89. /*
  90.  * GenInit()
  91.  *
  92.  * This does general initialization.
  93.  */
  94. void GenInit()
  95. {
  96.     SYS_FILE fn;
  97.  
  98.     initNetBuf(&netBuf);
  99.     makeSysName(fn, "ctdlnet.sys", &cfg.netArea);
  100.     openFile(fn, &netfl);
  101.  
  102.     initRoomBuf(&roomBuf);
  103.     makeSysName(fn, "ctdlroom.sys", &cfg.roomArea);
  104.     openFile(fn, &roomfl);
  105.  
  106.     makeSysName(fn, "ctdlmsg.sys", &cfg.msgArea);
  107.     openFile(fn, &msgfl);
  108. }
  109.  
  110. /*
  111.  * InitVirtual()
  112.  *
  113.  * This will read in the virtual stuff, create if necessary.
  114.  */
  115. void InitVirtual()
  116. {
  117.     FILE        *fd, *safeopen();
  118.     SYS_FILE    fn;
  119.     int         i, j;
  120.     long        len;
  121.     extern char *R_W_ANY, *W_R_ANY;
  122.  
  123.     ChkVirtArea();
  124.  
  125.     makeVASysName(fn, "ctdlvrm.sys");
  126.     if ((fd = safeopen(fn, R_W_ANY)) == NULL) {
  127.         splitIt("%s missing, creating it.\n", fn);
  128.         if ((fd = safeopen(fn, W_R_ANY)) == NULL) {
  129.             splitIt("Couldn't create the virtual room table!");
  130.             exit(1);
  131.         }
  132.         VirtSize = 0;
  133.     }
  134.     else {
  135.         totalBytes(&len, fd);
  136.         VRoomTab = (VirtualRoom *) GetDynamic((unsigned) len);
  137.         fread(VRoomTab, (int) len, 1, fd);
  138.         VirtSize = (int) ((int) len / sizeof *VRoomTab);
  139.     }
  140.     fclose(fd);
  141.  
  142.     VirtNetList = (VirtNet *)
  143.                         GetDynamic(cfg.netSize * (sizeof *VirtNetList));
  144.     makeVASysName(fn, "ctdlvnet.sys");
  145.     if ((fd = safeopen(fn, R_W_ANY)) == NULL) {
  146.         splitIt("%s missing, creating it.\n", fn);
  147.         if ((fd = safeopen(fn, W_R_ANY)) == NULL) {
  148.             splitIt("Couldn't create the network's virtual list (%s)!", fn);
  149.             exit(1);
  150.         }
  151.         for (i = 0; i < cfg.netSize; i++) {
  152.             for (j = 0; j < VIRT_LIMIT; j++) {
  153.                 VirtNetList[i].VirtList[j].WhichVirt = -1;      /* not in use */
  154.             }
  155.         }
  156.         fwrite(VirtNetList, sizeof *VirtNetList, cfg.netSize, fd);
  157.     }
  158.     else fread(VirtNetList, cfg.netSize * (sizeof *VirtNetList), 1, fd);
  159.     fclose(fd);
  160. }
  161.  
  162. /*
  163.  * UpdVirtStuff()
  164.  *
  165.  * This will update the disk about the virtual stuff.
  166.  */
  167. void UpdVirtStuff()
  168. {
  169.     FILE *fd, *safeopen();
  170.     SYS_FILE fn;
  171.     extern char *R_W_ANY;
  172.  
  173.     makeVASysName(fn, "ctdlvrm.sys");
  174.     if ((fd = safeopen(fn, R_W_ANY)) == NULL)
  175.         crashout("ctdlvrm.sys is missing!");
  176.  
  177.     fwrite(VRoomTab, VirtSize, sizeof *VRoomTab, fd);
  178.     fclose(fd);
  179.  
  180.     makeVASysName(fn, "ctdlvnet.sys");
  181.     if ((fd = safeopen(fn, R_W_ANY)) == NULL)
  182.         crashout("ctdlvnet.sys is missing!!");
  183.  
  184.     fwrite(VirtNetList, cfg.netSize, sizeof *VirtNetList,  fd);
  185.     fclose(fd);
  186. }
  187.  
  188. /*
  189.  * AnalyzeArguments()
  190.  *
  191.  * what are we to do???
  192.  */
  193. void AnalyzeArguments(argc, argv)
  194. int  argc;
  195. char **argv;
  196. {
  197.     int  rover;
  198.     SYS_FILE    fn;
  199.     extern char *APPEND_TEXT;
  200.  
  201.     RunMode = NORMAL;
  202.  
  203.     for (rover = 1; rover < argc; rover++) {
  204.         if (strCmpU(argv[rover], "+log") == SAMESTRING) {
  205.             makeSysName(fn, "netlog.sys", &cfg.netArea);
  206.             VaLog = safeopen(fn, APPEND_TEXT);
  207.         }
  208.         else if (strCmpU(argv[rover], "+batch") == SAMESTRING) {
  209.             RunMode = BATCH;
  210.         }
  211.     }
  212. }
  213.  
  214. /*
  215.  * InteractMode()
  216.  *
  217.  * This lets us talk to da sysop.
  218.  */
  219. void InteractMode()
  220. {
  221.     int answer;
  222.  
  223.     do {
  224.         splitIt("\n\n%30cVirtual Administrator Menu\n\n", ' ');
  225.         splitIt("A. Display Virtual Rooms.\n");
  226.         splitIt("B. Add a Virtual Room.\n");
  227.         splitIt("C. Modify a Virtual Room.\n");
  228.         splitIt("D. Delete a Virtual Room.\n");
  229.         splitIt("E. Convert a normal room to a virtual room.\n");
  230.         splitIt("F. Rename room.\n");
  231.         splitIt("Z. Exit the Virtual Room Administrator.\n");
  232.         switch ((answer = toUpper(NEUtilGetch()))) {
  233.         case 'A':
  234.                 Display();                      break;
  235.         case 'B':
  236.                 AddRoom();                      break;
  237.         case 'C':
  238.                 Modify();                       break;
  239.         case 'D':
  240.                 Delete();                       break;
  241.         case 'E':
  242.                 ConNorVa();                     break;
  243.         case 'F':
  244.                 VReName();                      break;
  245.         case 'Y':
  246.                 VADebug();                      break;
  247.         case 'Z':
  248.                                                 break;
  249.         default:
  250.                 printf("\007\n\n\n");           break;
  251.         }
  252.     } while (answer != EOF && answer != 'Z');
  253. }
  254.  
  255. /*
  256.  * AddRoom()
  257.  *
  258.  * This function will add a virtual room.
  259.  */
  260. void AddRoom()
  261. {
  262.     int   rover;
  263.     label NewName;
  264.     void  *realloc();
  265.  
  266.     if (GetConString("room name", NewName, NAMESIZE)) {
  267.         if (roomExists(NewName) != ERROR) {
  268.             splitIt("A real room by that name already exists.\n");
  269.             return ;
  270.         }
  271.         if (VirtualExists(NewName) != ERROR) {
  272.             splitIt("A virtual room by that name already exists.\n");
  273.             return ;
  274.         }
  275.  
  276.         rover = Add2Room(NewName);
  277.  
  278.         GetInputList(rover, "Nodes to be added to this virtual room's list",
  279.                                                 AddNodes);
  280.     }
  281. }
  282.  
  283. /*
  284.  * Add2Room()
  285.  *
  286.  * This does the rest of adding a room.
  287.  */
  288. int Add2Room(label NewName)
  289. {
  290.     int rover;
  291.  
  292.     for (rover = 0; rover < VirtSize; rover++)
  293.         if (!VRoomInuse(rover)) break;
  294.  
  295.     if (rover == VirtSize) {
  296.         if (rover == 0)
  297.             VRoomTab = (VirtualRoom *) GetDynamic(sizeof *VRoomTab);
  298.         else
  299.             VRoomTab = realloc(VRoomTab, (rover+1) * sizeof *VRoomTab);
  300.         VirtSize++;
  301.     }
  302.  
  303.     strCpy(VRoomTab[rover].vrName, NewName);
  304.  
  305.     VRoomTab[rover].vrHiLocal =
  306.     VRoomTab[rover].vrHiLD    =
  307.     VRoomTab[rover].vrLoLocal =
  308.     VRoomTab[rover].vrLoLD    = 0l;
  309.     SetVirtAreas(rover);
  310.  
  311.     return rover;
  312. }
  313.  
  314. /*
  315.  * VirtualExists()
  316.  *
  317.  * This function will check for existence of a virtual room.
  318.  */
  319. int VirtualExists(name)
  320. label name;
  321. {
  322.     int rover;
  323.  
  324.     for (rover = 0; rover < VirtSize; rover++)
  325.         if (strCmpU(VRoomTab[rover].vrName, name) == SAMESTRING) return rover;
  326.  
  327.     return ERROR;
  328. }
  329.  
  330. /*
  331.  * Delete()
  332.  *
  333.  * This function will delete a room from the virtual room table.
  334.  */
  335. void Delete()
  336. {
  337.     label NewName;
  338.     int   slot;
  339.  
  340.     if (GetConString("room name", NewName, NAMESIZE)) {
  341.         if ((slot = VirtualExists(NewName)) != ERROR)
  342.             if (getYesNo("confirm")) {
  343.                 VRoomKill(slot);
  344.                 KillVirtAreas(slot);
  345.                 ResetNodes(slot);
  346.             }
  347.     }
  348. }
  349.  
  350. /*
  351.  * ResetNodes()
  352.  *
  353.  * This function negates nodes attachments to a dead room.
  354.  */
  355. void ResetNodes(slot)
  356. int slot;
  357. {
  358.     int rover, j;
  359.  
  360.     for (rover = 0; rover < cfg.netSize; rover++) {
  361.         for (j = 0; j < VIRT_LIMIT; j++) {
  362.             if (VirtNetList[rover].VirtList[j].WhichVirt == slot)
  363.                 VirtNetList[rover].VirtList[j].WhichVirt = -1;
  364.         }
  365.     }
  366. }
  367.  
  368. /*
  369.  * GetConString()
  370.  *
  371.  * This function will get info from console.
  372.  */
  373. char GetConString(prompt, buffer, length)
  374. char *prompt, *buffer;
  375. int length;
  376. {
  377.     int count = 0, c;
  378.  
  379.     if (strLen(prompt) != 0)
  380.         splitIt("Enter %s (ESC to abort)", prompt);
  381.  
  382.     splitIt("\n : ");
  383.     while (c = UtilGetch(), c != '\r' && c != '\n' && c != ESC) {
  384.         if ((c != '\b' && count == length) ||
  385.             (c == '\b' && count == 0)) {
  386.             if (c != '\b') splitIt("\b \b\007");
  387.             else           splitIt("\007");
  388.         }
  389.         else if (c != '\b') {
  390.             buffer[count++] = c;
  391.         }
  392.         else {
  393.             splitIt(" \b");
  394.             count--;
  395.         }
  396.     }
  397.     buffer[count] = 0;
  398.     if (c == ESC || strLen(buffer) == 0)
  399.         return FALSE;
  400.     return TRUE;
  401. }
  402.  
  403. /*
  404.  * getYesNo()
  405.  *
  406.  * This gets a Y/N question of the user.
  407.  */
  408. char getYesNo(question)
  409. char *question;
  410. {
  411.     int c;
  412.  
  413.     do {
  414.         splitIt("\n%s (Y/N)? ", question);
  415.         c = toUpper(UtilGetch());
  416.     } while (c != 'Y' && c != 'N');
  417.     return (char)( (c == 'Y') ? TRUE : FALSE);
  418. }
  419.  
  420. /*
  421.  * Modify()
  422.  *
  423.  * This function will add and kill nodes from a sharing list.
  424.  */
  425. void Modify()
  426. {
  427.     label NewName;
  428.     int   slot, AddNodes(), RemoveNodes();
  429.  
  430.     if (GetConString("room name", NewName, NAMESIZE)) {
  431.         if ((slot = VirtualExists(NewName)) == ERROR) {
  432.             splitIt("'%s' does not exist.\n", NewName);
  433.             return ;
  434.         }
  435.         GetInputList(slot, "Nodes to be added to this virtual room's list",
  436.                                                 AddNodes);
  437.         GetInputList(slot, "Nodes to be taken off this virtual room's list",
  438.                                                 RemoveNodes);
  439.         GetInputList(slot, "Nodes to be changed", ChgNodes);
  440.     }
  441. }
  442.  
  443. /*
  444.  * GetInputList()
  445.  *
  446.  * This function will process lists entered by user.
  447.  */
  448. void GetInputList(index, prompt, func)
  449. int index, (*func)(int index, label name);
  450. char *prompt;
  451. {
  452.     label data;
  453.  
  454.     splitIt(prompt);
  455.     while (GetConString("", data, NAMESIZE))
  456.         if (!(*func)(index, data)) break;
  457. }
  458.  
  459. /*
  460.  * AddNodes()
  461.  *
  462.  * This adds a node to room's share list.
  463.  */
  464. int AddNodes(index, name)
  465. int index;
  466. label name;
  467. {
  468.     int rover, system, c, found;
  469.  
  470.     if ((system = searchNameNet(name, &netBuf)) == ERROR) {
  471.         splitIt("No such system known.");
  472.         return TRUE;
  473.     }
  474.  
  475.     for (rover = 0, found = FALSE; rover < VIRT_LIMIT; rover++)
  476.         if (index == VirtNetList[system].VirtList[rover].WhichVirt) {
  477.             found = TRUE;
  478.             break;
  479.         }
  480.  
  481.     if (!found)
  482.         for (rover = 0; rover < VIRT_LIMIT; rover++)
  483.             if (VirtNetList[system].VirtList[rover].WhichVirt == -1) {
  484.                 break;
  485.             }
  486.  
  487.     if (rover == VIRT_LIMIT) {
  488.         splitIt("Sorry, no room.");
  489.         return TRUE;
  490.     }
  491.  
  492.     if (!getYesNo("Is this system a Peon")) {
  493.         do {
  494.             splitIt("\nWill we be a <P>assive or <A>ctive backbone? ");
  495.             c = toUpper(UtilGetch());
  496.         } while (c != 'A' && c != 'P');
  497.         VirtNetList[system].VirtList[rover].mode =
  498.         (c == 'A') ? ACTIVE_BACKBONE : PASS_BACKBONE;
  499.     }
  500.     else
  501.         VirtNetList[system].VirtList[rover].mode = PEON;
  502.  
  503.     VirtNetList[system].VirtList[rover].WhichVirt = index;
  504.  
  505.     if (!found) {
  506.         VirtNetList[system].VirtList[rover].LocSent   =
  507.            VRoomTab[index].vrLoLocal;
  508.         VirtNetList[system].VirtList[rover].LDSent    =
  509.            VRoomTab[index].vrLoLD;
  510.     }
  511.  
  512.     return TRUE;
  513. }
  514.  
  515. /*
  516.  * RemoveNodes()
  517.  *
  518.  * This function will remove a node from a room's share list.
  519.  */
  520. int RemoveNodes(index, name)
  521. int index;
  522. label name;
  523. {
  524.     int system, rover;
  525.  
  526.     if ((system = searchNameNet(name, &netBuf)) == ERROR) {
  527.         splitIt("No such system known.\n");
  528.         return TRUE;
  529.     }
  530.     for (rover = 0; rover < VIRT_LIMIT; rover++)
  531.         if (index == VirtNetList[system].VirtList[rover].WhichVirt) {
  532.             VirtNetList[system].VirtList[rover].WhichVirt = -1;
  533.             return TRUE;
  534.         }
  535.     return TRUE;
  536. }
  537.  
  538. /*
  539.  * ChgNodes()
  540.  *
  541.  * This function will change a node's status.
  542.  */
  543. int ChgNodes(index, name)
  544. int index;
  545. label name;
  546. {
  547.     int system, rover;
  548.  
  549.     if ((system = searchNameNet(name, &netBuf)) == ERROR) {
  550.         splitIt("No such system known.\n");
  551.         return TRUE;
  552.     }
  553.     for (rover = 0; rover < VIRT_LIMIT; rover++)
  554.         if (index == VirtNetList[system].VirtList[rover].WhichVirt) {
  555.             splitIt("Currently, ");
  556.             switch (VirtNetList[system].VirtList[rover].mode) {
  557.             case PEON:
  558.                 splitIt("you think of %s as a Peon.", name); break;
  559.             case ACTIVE_BACKBONE:
  560.                 splitIt("you are an Active Backbone for %s.", name); break;
  561.             case PASS_BACKBONE:
  562.                 splitIt("you are a Passive Backbone for %s.", name); break;
  563.             }
  564.  
  565.             splitIt("\nDo you wish to change the relationship to\n");
  566.             splitIt("1. Peon\n2. You are Active Backbone\n");
  567.             splitIt("3. Passive Backbone.\n? ");
  568.  
  569.             switch (NEUtilGetch()) {
  570.             case '1':
  571.             VirtNetList[system].VirtList[rover].mode = PEON; break;
  572.             case '2':
  573.             VirtNetList[system].VirtList[rover].mode = ACTIVE_BACKBONE; break;
  574.             case '3':
  575.             VirtNetList[system].VirtList[rover].mode = PASS_BACKBONE; break;
  576.             }
  577.  
  578.             return TRUE;
  579.         }
  580.     return TRUE;
  581. }
  582.  
  583. /*
  584.  * crashout()
  585.  *
  586.  * This handles fatal errors.
  587.  */
  588. void crashout(str)
  589. char *str;
  590. {
  591.     printf(str);
  592.     writeSysTab();
  593.     UpdVirtStuff();
  594.     exit(1);
  595. }
  596.  
  597. /*
  598.  * BatchMode()
  599.  *
  600.  * This handles batch mode calls.
  601.  */
  602. void BatchMode()
  603. {
  604.     struct Table_Summary {
  605.         MSG_NUMBER LoLocal, LoLD;
  606.     } *Summary;
  607.     int rover, checker, x;
  608.     MSG_NUMBER msgrover;
  609.     char buf[100];
  610.  
  611.     if (VirtSize == 0) return;
  612.  
  613.     Summary = (struct Table_Summary *) GetDynamic(VirtSize * sizeof *Summary);
  614. /*
  615.  * For each virtual room in use:
  616.  *
  617.  * 1. Determine which PEON-generated messages have been delivered to
  618.  *    all BACKBONES and kill those messages.
  619.  * 2. Update appropriate values.
  620.  * 3. Determine which BACKBONE-generated messages have been delivered to
  621.  *    other BACKBONES and PEONS, and kill them.
  622.  * 4. Update appropriate values.
  623.  *
  624.  *   The code that accepts and places messages in the correct places resides
  625.  * in the main source, not here.  Briefly:
  626.  *
  627.  * a. Each Virtual Room has a directory within the VIRTUAL\ subdirectory
  628.  *    dedicated to it.  Mapping of Room to directory is to use the slot # of
  629.  *    the Virtual room as a string for the directory name.  This will limit the
  630.  *    system to, at best, 11 digits.  Even if the limit is 8 digits, however,
  631.  *    that should be more than adequate.
  632.  * b. Each Room's subdirectory consists of two more subdirectories, arbitrarily
  633.  *    labeled.  Messages which arrive from BACKBONE systems
  634.  *    are placed in the "ld" directory; messages from PEONS are placed in the
  635.  *    "local" directory.
  636.  * c. Message structure: Each message that is accepted from another system is
  637.  *    NOT kept in a separate file.  Rather, each packet of messages is kept
  638.  *    in a file.  This should work just as well, and save on clutter.
  639.  * d. Each file kept in either directory will be given a name consisting of an
  640.  *    integer generated by incrementing a counter associated with that
  641.  *    directory.  Counters are independent of each other.
  642.  * e. The Virtual net list is used to track who needs what, using these
  643.  *    counters.  When messages are sent to a system, the number of the last
  644.  *    packet sent is recorded.  Possible problem: a BACKBONE calling -- how
  645.  *    do we keep from looping the messages back to the caller on the LD room
  646.  *    share?  OK, looks like we'll have to put it in a temp file, and rename
  647.  *    it later.  No, we can just remember to increment the number later, and
  648.  *    just not resend it now.
  649.  */
  650.     for (rover = 0; rover < VirtSize; rover++)
  651.         Summary[rover].LoLocal = Summary[rover].LoLD = 0xffffffffl;
  652.  
  653.     for (rover = 0; rover < cfg.netSize; rover++) {
  654.         if (netTab[rover].ntflags.in_use)
  655.         for (checker = 0; checker < VIRT_LIMIT; checker++) {
  656.             if ((x = VirtNetList[rover].VirtList[checker].WhichVirt) >= 0 &&
  657.                                 x < VirtSize) {
  658. /* splitIt("x is %d\n", x); */
  659. /* if (x > VirtSize) splitIt("BINGO!\n"); */
  660.                 if (VirtNetList[rover].VirtList[checker].mode != PEON)
  661.                     Summary[x].LoLocal =
  662.       min(Summary[x].LoLocal, VirtNetList[rover].VirtList[checker].LocSent);
  663.                 Summary[x].LoLD =
  664.       min(Summary[x].LoLD, VirtNetList[rover].VirtList[checker].LDSent);
  665.             }
  666.             else if (x >= VirtSize) {
  667.                 splitIt("x is high for system %d, correcting.\n", rover);
  668.                 VirtNetList[rover].VirtList[checker].WhichVirt = -1;
  669.             }
  670.         }
  671.     }
  672.  
  673.     for (rover = 0; rover < VirtSize; rover++) {
  674.         if (VRoomInuse(rover)) {
  675.  
  676.             if (Summary[rover].LoLocal == 0xffffffffl)
  677.                 Summary[rover].LoLocal = 0l;
  678.             if (Summary[rover].LoLD == 0xffffffffl)
  679.                 Summary[rover].LoLD = 0l;
  680.  
  681.             for (msgrover = max(VRoomTab[rover].vrLoLocal, 1l);
  682.                  msgrover <= Summary[rover].LoLocal; msgrover++) {
  683.                 CreateVAName(buf, rover, LOCAL_DIR, msgrover);
  684.                 splitIt("Unlinking %s\n", buf);
  685.                 unlink(buf);
  686.             }
  687.             VRoomTab[rover].vrLoLocal = msgrover;
  688.             for (msgrover = max(VRoomTab[rover].vrLoLD, 1l);
  689.                  msgrover <= Summary[rover].LoLD; msgrover++) {
  690.                 CreateVAName(buf, rover, LD_DIR, msgrover);
  691.                 splitIt("Unlinking %s\n", buf);
  692.                 unlink(buf);
  693.             }
  694.             VRoomTab[rover].vrLoLD = msgrover;
  695.         }
  696.     }
  697.  
  698.     free(Summary);
  699. }
  700.  
  701. /*
  702.  * roomExists()
  703.  *
  704.  * This will check for existence of a real room.
  705.  */
  706. int roomExists(room)
  707. char *room;
  708. {
  709.     int i;
  710.  
  711.     for (i = 0;  i < MAXROOMS;  i++) {
  712.         if (
  713.             roomTab[i].rtflags.INUSE == 1   &&
  714.             strCmpU(room, roomTab[i].rtname) == SAMESTRING
  715.         ) {
  716.             return(i);
  717.         }
  718.     }
  719.     return(ERROR);
  720. }
  721.  
  722. /*
  723.  * Display()
  724.  *
  725.  * This will give a crude display of virtual rooms and nodes attached.
  726.  */
  727. void Display()
  728. {
  729.     int rover, i, len, netRover;
  730.     char first;
  731.  
  732.     splitIt("\n\n\nVirtual Room Display\n\n");
  733.     for (rover = 0; rover < VirtSize; rover++) {
  734.         if (VRoomInuse(rover)) {
  735.             splitIt("%s> ", VRoomTab[rover].vrName);
  736.             for (i = strLen(VRoomTab[rover].vrName); i < 22; i++)
  737.                 splitIt(".");
  738.             splitIt(" ");
  739.             len = 44;   /* crude formatter */
  740.             first = TRUE;
  741.             for (netRover = 0; netRover < cfg.netSize; netRover++) {
  742.                 if (DoesShare(netRover, rover) != ERROR) {
  743.                     getNet(netRover, &netBuf);
  744.                     if (!first)
  745.                         splitIt(", ");
  746.                     else first = FALSE;
  747.                     if (2 + len + strLen(netBuf.netName) > 80) {
  748.                         splitIt("\n%24c", ' ');
  749.                         len = 23;
  750.                     }
  751.                     splitIt("%s", netBuf.netName);
  752.                     len += (2 + strLen(netBuf.netName));
  753.                 }
  754.             }
  755.             splitIt("\n");
  756.         }
  757.     }
  758. }
  759.  
  760. /*
  761.  * DoesShare()
  762.  *
  763.  * This function will find out if the given node shares the given room.
  764.  */
  765. int DoesShare(NodeNo, RoomNo)
  766. int NodeNo, RoomNo;
  767. {
  768.     int i;
  769.  
  770.     if (!netTab[NodeNo].ntflags.in_use) return ERROR;
  771.  
  772.     for (i = 0; i < VIRT_LIMIT; i++) {
  773.         if (VirtNetList[NodeNo].VirtList[i].WhichVirt == RoomNo)
  774.             return i;
  775.     }
  776.     return ERROR;
  777. }
  778.  
  779. void VADebug()
  780. {
  781.     int i, j, x;
  782.  
  783.     for (i = 0; i < cfg.netSize; i++) {
  784.         for (j = 0; j < VIRT_LIMIT; j++) {
  785.             if ((x=VirtNetList[i].VirtList[j].WhichVirt) != -1) {
  786.                 if (VRoomInuse(x)) {
  787.                     getNet(i, &netBuf);
  788.                     printf("%s for %s: ", netBuf.netName,
  789.                                 VRoomTab[x].vrName);
  790.                     printf("LocSent=%ld, LocHi=%ld, ",
  791.                               VirtNetList[i].VirtList[j].LocSent,
  792.                               VRoomTab[x].vrHiLocal);
  793.                     printf("LDSent=%ld, LDHI=%ld\n",
  794.                               VirtNetList[i].VirtList[j].LDSent,
  795.                               VRoomTab[x].vrHiLD);
  796.                 }
  797.             }
  798.         }
  799.     }
  800. }
  801.  
  802. /*
  803.  * ConNorVa()
  804.  *
  805.  * This function converts a normal room to a virtual
  806.  * 1. Make new virtual room.
  807.  * 2. Convert msg base messages to files, one per msg.  Route to correct
  808.  *    directories
  809.  * 3. Update VirtNetList.
  810.  * 4. Delete old room.
  811.  */
  812. void ConNorVa()
  813. {
  814.     int   rover, roomNo;
  815.     label Name;
  816.     void  *realloc();
  817.     TempData *List;
  818.  
  819.     if (GetConString("Normal room name", Name, NAMESIZE)) {
  820.         if ((roomNo = roomExists(Name)) == ERROR) {
  821.             splitIt("There is no room by that name.\n");
  822.             return ;
  823.         }
  824.  
  825.         if (!getYesNo("confirm")) return ;
  826.  
  827.         rover = Add2Room(Name);
  828.  
  829.         getRoom(roomNo);
  830.  
  831.         if (roomBuf.rbShareType == PEON)
  832.             splitIt("Warning: %s is not being backboned at the present time.\n",
  833.                                 roomBuf.rbname);
  834.  
  835.         List = SetNtoVList(roomNo, rover);
  836.  
  837.         NorToVirtual(rover, List);
  838.  
  839.         roomBuf.rbflags.INUSE = FALSE;
  840.  
  841.         putRoom(roomNo);
  842.  
  843.         roomTab[roomNo].rtflags.INUSE = FALSE;
  844.  
  845.         writeSysTab();
  846.     }
  847. }
  848.  
  849. /*
  850.  * VRename
  851.  *
  852.  * This function renames a virtual room.
  853.  */
  854. void VReName()
  855. {
  856.     label NewName, OldName;
  857.     int slot;
  858.  
  859.     if (!GetConString("old room name", OldName, NAMESIZE)) return;
  860.  
  861.     if ((slot = VirtualExists(OldName)) != ERROR) {
  862.         if (GetConString("new room name", NewName, NAMESIZE)) {
  863.             if (roomExists(NewName) != ERROR) {
  864.                 splitIt("A real room by that name already exists.\n");
  865.                 return ;
  866.             }
  867.             if (VirtualExists(NewName) != ERROR) {
  868.                 splitIt("A virtual room by that name already exists.\n");
  869.                 return ;
  870.             }
  871.             strCpy(VRoomTab[slot].vrName, NewName);
  872.         }
  873.     }
  874.     else splitIt("No such virtual room.\n");
  875. }
  876.  
  877. #ifdef NEEDED
  878. void LogSetup()
  879. {
  880. }
  881.  
  882. FILE *lfd = NULL;
  883. extern LogTable    *logTab;
  884. LogTable    *delogTab;
  885. void LogCheck(char *x)
  886. {
  887.     int i;
  888.  
  889.     if (lfd != NULL) return;
  890.     if (delogTab == NULL) {
  891.         delogTab = (LogTable *) GetDynamic(sizeof (*logTab) * cfg.MAXLOGTAB);
  892.         memcpy(delogTab, logTab, (long)sizeof (*logTab) * cfg.MAXLOGTAB);
  893.     }
  894.     for (i = 0; i < cfg.MAXLOGTAB; i++)
  895.         if (logTab[i].ltlogSlot >= cfg.MAXLOGTAB ||
  896.             logTab[i].ltlogSlot < 0 ||
  897.             logTab[i].ltpwhash != delogTab[i].ltpwhash ||
  898.             logTab[i].ltnmhash != delogTab[i].ltnmhash) {
  899.             if ((lfd = fopen("debug", "a")) != NULL) {
  900.                 fprintf(lfd, "Blargh at -%s- in VIRTADMN for index %d!\n",
  901.                                         x, i);
  902.                 fclose(lfd);
  903.             }
  904.             else printf("Blargh at -%s-!\n", x);
  905.             break;
  906.         }
  907. }
  908.  
  909. void splitF(FILE *log, char *fmt, ...)
  910. {
  911. }
  912. #endif
  913.